use derive_more::Display;
use salvo::prelude::*;
use serde_json::json;
use std::io;
use thiserror::Error;

#[derive(Debug, Display, Error)]
pub enum MyErr {
    #[display(fmt = "系统IO异常，请联系管理员！")]
    Io(#[from] io::Error),

    #[display(fmt = "数据库操作异常，请联系管理员！")]
    Db(#[from] sqlx::Error),

    #[display(fmt = "参数格式转换错误，请联系管理员！")]
    ParseError(#[from] salvo::http::ParseError),

    #[display(fmt = "JSON转换错误，请联系管理员！")]
    JsonError(#[from] serde_json::Error),

    #[display(fmt = "系统忙，请稍后在试！")]
    Other(#[from] anyhow::Error),

    #[display(fmt = "系统忙，请稍后在试！")]
    System(String),

    // 该错误信息会直接显示给前台用户
    Msg(String),

    // 该错误信息会直接显示给前台用户
    #[display(fmt = "系统忙，请稍后在试！")]
    Errcode((i64, String)),
}

#[async_trait]
impl Writer for MyErr {
    async fn write(mut self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
        match &self {
            MyErr::Io(e) => log::error!("{}", e),
            MyErr::Db(e) => log::error!("{}", e),
            MyErr::ParseError(e) => log::error!("{}", e),
            MyErr::JsonError(e) => log::error!("{}", e),
            MyErr::System(e) => log::error!("{}", e),
            MyErr::Other(e) => log::error!("{}", e),
            MyErr::Errcode((i, s)) => log::error!("错误：{} 代码：{}", s, i),
            _ => (),
        };

        // res.render(Json(ResBean {
        //     code: -900,
        //     msg: self.to_string(),
        //     bundle: None,
        // }));

        res.render(Json(json!({
            "code" :  -900,
            "msg": self.to_string(),
        })));
    }
}
